#include <stdio.h>
#include <stdlib.h>
#include <string.h>


typedef struct Song {
    char name[100];
    char artist[50];
    int duration;
    int play_count;
    struct Song *next;
} Song;

typedef struct {
    Song **songs;
    int front;
    int rear;
    int capacity;
    int size;
    int is_random;
    int current;
} PlayerQueue;

typedef struct {
    Song *head;
    Song *tail;
    int count;
} Playlist;
typedef struct {
    Song **items;
    int top;
    int base;
    int stacksize;
} Stack;

typedef struct {
    Playlist *playlist;
    PlayerQueue *queue;
    Stack *history;
    Song *current_song;
} MusicPlayer;




void init_stack(Stack *stac, int size) {
    stac->items = (Song**)malloc(size * sizeof(Song*));
    if (!stac->items) {
        printf("error\n");
        exit(1);
    }
    stac->top = 0;
    stac->base = 0;
    stac->stacksize = size;
}


int is_stack_full(Stack *stac) {
    return stac->top == stac->stacksize;
}


int is_stack_empty(Stack *stac) {
    return stac->top == stac->base;
}


void push_to_stack(Stack *stac, Song *song) {
    int i;
    if (is_stack_full(stac)) {

        for ( i = 1; i < stac->top; i++) {
            stac->items[i-1] = stac->items[i];
        }
        stac->top--;
    }
    stac->items[stac->top++] = song;
}


Song* pop_from_stack(Stack *stac) {
    if (is_stack_empty(stac)) {
        return NULL;
    }
    return stac->items[--stac->top];
}


Song* peek_stack(Stack *stac) {
    if (is_stack_empty(stac)) {
        return NULL;
    }
    return stac->items[stac->top-1];
}


void free_stack(Stack *stac) {
    free(stac->items);
    stac->items = NULL;
    stac->top = stac->base = 0;
}

void init_music_player(MusicPlayer *player, int playlist_size, int queue_size, int history_size) {
    player->playlist = (Playlist*)malloc(sizeof(Playlist));
    init_playlist(player->playlist);

    player->queue = (PlayerQueue*)malloc(sizeof(PlayerQueue));
    init_player_queue(player->queue, queue_size);

    player->history = (Stack*)malloc(sizeof(Stack));
    init_stack(player->history, history_size);

    player->current_song = NULL;
}


Song* player_play_next(MusicPlayer *player) {
    Song *next_song = play_next(player->queue);
    if (next_song) {

        if (player->current_song) {
            push_to_stack(player->history, player->current_song);
        }
        player->current_song = next_song;
    }
    return next_song;
}


Song* player_play_prev(MusicPlayer *player) {
    Song *prev_song = pop_from_stack(player->history);
    if (prev_song) {

        player->current_song = prev_song;
    }
    return prev_song;
}


void free_music_player(MusicPlayer *player) {
    free_playlist(player->playlist);
    free(player->playlist);

    free(player->queue);

    free_stack(player->history);
    free(player->history);
}

/**
 * @brief 打印播放列表（带播放次数）
 *
 * @param playlist 播放列表指针
 */
void print_playlist_with_count(const Playlist *playlist) {
   if (playlist == NULL) {
        printf("Playlist is invalid.\n");
        return;
    }

    Song *current = playlist->head;
    int i = 1;
    if (current != NULL) {

        char safe_name[100] = {0};
        char safe_artist[50] = {0};
        strncpy(safe_name, current->name, sizeof(safe_name)-1);
        strncpy(safe_artist, current->artist, sizeof(safe_artist)-1);

        printf("%d. %s - %s \n",
               i++, safe_name, safe_artist);


        Song *next = current->next;


        if ((void*)next == (void*)current) {
            printf("Error: Circular reference detected!\n");
            return;
        }

        current = next;
    }


    if (i-1 != playlist->count) {
        printf("Warning: Actual count (%d) differs from playlist count\n",
               i-1);
    }
}
